#!/usr/bin/env python
# -*- coding: utf-8 -*-

import tornado.web
import datetime
import hashlib
import math
import hashlib
import Image
import tempfile
import re
import ConfigParser
import time
import pymongo

from pymongo import objectid

class BaseHandler(tornado.web.RequestHandler):
    def prepare(self):
        if not hasattr(self,"id"):
            if self.get_secure_cookie("id") and self.get_secure_cookie("gid")=="9":
                self.uid = self.get_secure_cookie("id")
                self.name = self.get_secure_cookie("name")
                self.nickname = self.get_secure_cookie("nickname")
                self.gid = self.get_secure_cookie("gid")
                self.email = self.get_secure_cookie("email")
            else:
                self.finish("Access Denied!")
                
    def initialize(self):
        self.bcore = pymongo.Connection().bcore
        opt = {}
        opt['login'] = False
        opt['nowdate'] = self.nowdate
        opt['nowtime'] = self.nowtime
        opt['cats'] = self.bcore.cats.find()
        self.opt = opt

    @property
    def nowdate(self):
        return str(datetime.datetime.now()).split(" ")[0]
    
    @property
    def nowtime(self):
        return datetime.datetime.now()
    
    
# 文章列表
class PostsHandler(BaseHandler):
    def get(self,args):
        if args and args.split("/"):
            action,page =  args.split('/')
        else:
            action,page = ['publish',1]
        page = page and int(page) or 1
        start,end = int((page -1)*30.0),30
        url = '/a/posts/'+action+'/'
        self.opt['posts'] = {}
        self.opt['action'] = action
        self.opt['posts']['rowset'] = self.bcore.posts.find({"status":action},{"content":0,"excerpt":0}).sort([("top",pymongo.DESCENDING),("ctime",pymongo.DESCENDING)])[start:start+end]
        self.opt['posts']['url'] = url
        self.opt['posts']['page'] = page
        self.render("posts.html",xsrf_token=self.xsrf_token,**self.opt)
        
    def post(self,args):
        action = self.get_argument("action",default="")
        if action:
            method = getattr(self,action)
            pid = self.get_argument("postid","0")
            method(pid)

    def top(self,pid):
        post = self.bcore.posts.find_one({"_id":objectid.ObjectId(pid)})
        post["top"] = math.fabs(post["top"]-1)
        self.bcore.posts.update({"_id":objectid.ObjectId(pid)},post)
        self.write(str(pid))

    def delete(self,pid):
        self.bcore.posts.remove({"_id":objectid.ObjectId(pid)})
        self.write(str(pid))

# 站点设置
class SettingHandler(BaseHandler):
    def get(self,action):
        if action == "profile":
            profile = self.bcore.options.find_one({"type":"profile"})
            profile = profile and profile['val'] or ""
            self.render("setting_profile.html",profile=profile,**self.opt)
        elif action == "link":
            self.opt["links"] = self.bcore.options.find({"type":"link"})
            self.render("setting_link.html",**self.opt)
        else:
            self.opt["site_options"] = self.site_options()
            self.render("setting.html",**self.opt)

    def post(self,action):
        if action == "profile":
            profile = self.get_argument("profile","")
            self.bcore.options.update({"type":"profile"},{"$set":{"val":profile}})
            self.redirect('/a/setting/profile/')
        elif action == "link":
            key = self.get_argument("sitename",default="")
            val = self.get_argument("uri",default="")
            com = self.get_argument("comment",default="")
            link = {"key":key,"val":val,"comment":com,"type":"link"}
            self.bcore.options.insert(link)
            self.redirect('/a/setting/link/')
        else:
            action = "site"
            sitename = self.get_argument("sitename",default="")
            gacode = self.get_argument("gacode",default="")
            default_limit = self.get_argument("default_limit",10)
            self.site_save(sitename=sitename,gacode=gacode,default_limit=default_limit)
            self.redirect('/a/setting/')

    def site_save(self,gacode="",default_limit=10,sitename=""):
        cf = ConfigParser.ConfigParser()
        cf.read("config.conf")
        cf.set("setting","limit",default_limit)
        cf.set("setting","sitename",sitename)
        cf.set("setting","gacode",gacode)
        cf.write(open("config.conf","w"))

    def site_options(self):
        options = {}
        cf = ConfigParser.ConfigParser()
        cf.read("config.conf")
        options["default_limit"] = cf.getint("setting","limit")
        options["sitename"] = cf.get("setting","sitename")
        options["gacode"] = cf.get("setting","gacode")
        return options



# 相册列表
class FilesHandler(BaseHandler):
    def get(self,args):
        if args and args.split("/"):
            action,page =  args.split('/')
        else:
            action,page = ['publish',1]
        page = page and int(page) or 1
        start,end = int((page -1)*30.0),30
        url = '/a/files/'+action+'/'
        self.opt['files'] = {}
        self.opt['action'] = action
        self.opt['files']["rowset"] = self.bcore.files.find({"status":action})[start:end+start]
        self.opt['files']['url'] = url
        self.opt['files']['page'] = page
        self.render("files.html",**self.opt)

# 文章内使用图片发布接口
class PostfileHandler(BaseHandler):
    def get(self):
        self.render("postfile.html")

    def post(self):
        if self.request.files:
            for f in self.request.files['postfile']:
                rawname = f['filename']
                dstname = str(int(time.time()))+'.'+rawname.split('.').pop()
                thbname = "thumb_"+dstname
                # write a file
                # src = "./static/upload/src/"+dstname
                # file(src,'w+').write(f['body'])
                tf = tempfile.NamedTemporaryFile()
                tf.write(f['body'])
                tf.seek(0)
                
                # create normal file
                # img = Image.open(src)
                img = Image.open(tf.name)
                img.thumbnail((920,920),resample=1)
                img.save("./static/upload/postfiles/"+dstname)

                # create thumb file
                img.thumbnail((100,100),resample=1)
                img.save("./static/upload/postfiles/"+thbname)

                tf.close()
            self.write("""<script type="text/javascript">top.alertFinish("%s");</script>""" % (dstname))
        else:
            self.write("""None""")

# 文章curd                       
class PostHandler(BaseHandler):
    def get(self,args):
        jobs = args.split(".")
        
        # 包含点为删除
        if len(jobs)>1:
            self.delete(jobs[1])
            self.redirect("/a/posts/")

        # 普通情况读取(edit)
        elif args:
            post = self.bcore.posts.find_one({"_id":objectid.ObjectId(args)})
            self.render("edit.html",post=post,**self.opt)
        
        # 创建新文本
        else:
            self.render("compose.html",**self.opt)

    def post(self,args):
        postid = args.replace("/","")
        try:
            if postid and int(postid):
                self.create(postid)
            else:
                raise ValueError
        except ValueError:
            self.create(args)
            self.redirect("/a/posts/")
    
    #  新建/更新一个文章
    def create(self,args):
        post = {}

        # 取出数据
        if args:
            post = self.bcore.posts.find_one({"_id":objectid.ObjectId(args)})

        title,content,excerpt,ntime,status = self.get_argument("title"),self.get_argument("content",strip=False),self.get_argument("excerpt",default="",strip=False),self.nowtime,(self.get_argument("submit")).lower()
        cats = self.get_argument("cats",default="").split(",")
        extra = self.get_argument("extra",default="").split(";")
        content = re.sub(r"\s#time\s",lambda m:" [ "+datetime.datetime.now().ctime()+" ] ",content)
        post["content"] = content
        post["title"] = title
        post["excerpt"] = excerpt
        post["mtime"] = ntime
        post["status"] = status
        post["cats"] = cats
        post["extra"] = extra
        
        # 更新
        if args:
            self.bcore.posts.update({"_id":objectid.ObjectId(args)},post)

        # 创建
        else:
            post["ctime"] = ntime
            post["top"] = 0
            self.bcore.posts.insert(post)

            
        self.redirect("/a/posts/")

    def delete(self,args):
        self.write(args)

# 统计报表
class DashboardHandler(BaseHandler):
    def get(self,args):
        self.render("dashboard.html",**self.opt)

    def post(self,args):
        pass

# 上传操作
class UploadHandler(BaseHandler):
    def get(self,args):
        self.render("upload.html",**self.opt)

    def post(self,args):
        cats = self.get_argument("cats",default="").split(",")
        caption,content,ntime,status = self.get_argument('caption',default=''),self.get_argument('content',default=''),self.nowtime,'publish'
        if self.request.files:
            for f in self.request.files['upload']:
                rawname = f['filename']
                dstname = hashlib.md5(rawname).hexdigest()+'.'+rawname.split('.').pop()

                # write a file
                # src = "./static/upload/src/"+dstname
                # file(src,'w+').write(f['body'])
                tf = tempfile.NamedTemporaryFile()
                tf.write(f['body'])
                tf.seek(0)
                
                # create normal file
                # img = Image.open(src)
                img = Image.open(tf.name)
                img.thumbnail((920,920),resample=1)
                img.save("./static/upload/normal/"+dstname)

                # create thumb file
                img.thumbnail((100,100),resample=1)
                img.save("./static/upload/thumb/"+dstname)

                # add files info
                f = {"caption":caption,"content":content,"rawname":f['filename'],"dstname":dstname,"uid":self.uid,"ctime":ntime,"mtime":ntime,"status":status,"cats":cats}
                self.bcore.files.insert(f)
                
                tf.close()
                
        self.redirect("/a/files/")
        

        
# 登录/登出
class AuthHandler(BaseHandler):
    def prepare(self):
        pass

    def get(self,*args):
        for name in ["uid","gid","email","nickname"]:
            self.clear_cookie(name)
        self.render("login.html",login=True)
    
    def post(self):
        password = hashlib.md5(self.get_argument("password",'none')).hexdigest()
        username = self.get_argument("name",'none')
        user = self.bcore.users.find_one({"name":username,"password":password},{"password":0})
        if user:
            for key in ["name","nickname","id","gid","email"]:
                self.set_secure_cookie(key,str(user[key]))
            self.redirect("/a/dashboard/")
        else:
            self.redirect("/login")
